home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume89 / languags / motoasem.1 < prev    next >
Text File  |  1989-03-15  |  52KB  |  2,375 lines

  1. Path: xanth!nic.MR.NET!hal!cwjcc!mailrus!ulowell!page
  2. From: page@swan.ulowell.edu (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v89i055:  moto-assem - m68k assember from motorola's bbs, Part01/02
  5. Message-ID: <12237@swan.ulowell.edu>
  6. Date: 15 Mar 89 18:39:37 GMT
  7. Organization: University of Lowell, Computer Science Dept.
  8. Lines: 2364
  9. Approved: page@swan.ulowell.edu
  10.  
  11. Submitted-by: gmg@hcx.uucp (Greg Garner)
  12. Posting-number: Volume 89, Issue 55
  13. Archive-name: langauges/moto-assem.1
  14.  
  15. These files came from the Motorola Freeware BBS. Their BBS now has an
  16. amiga upload/download section (YEA!). I obtained explicit permission
  17. to post these to comp.sources.amiga and also to give these files to
  18. Fred Dish for inclusion in one of his disks.
  19.  
  20. #    This is a shell archive.
  21. #    Remove everything above and including the cut line.
  22. #    Then run the rest of the file through sh.
  23. #----cut here-----cut here-----cut here-----cut here----#
  24. #!/bin/sh
  25. # shar:    Shell Archiver
  26. #    Run the following text with /bin/sh to create:
  27. #    AS.C
  28. #    AS.H
  29. #    AS0.C
  30. #    AS1.C
  31. #    AS11.C
  32. #    AS4.C
  33. #    AS5.C
  34. #    AS9.C
  35. #    DO0.C
  36. #    DO1.C
  37. #    DO11.C
  38. #    DO4.C
  39. #    DO5.C
  40. #    DO9.C
  41. #    FFWD.C
  42. #    OUTPUT.C
  43. #    PSEUDO.C
  44. # This archive created: Wed Mar 15 13:33:52 1989
  45. cat << \SHAR_EOF > AS.C
  46. char mapdn();
  47. char *alloc();
  48. /*
  49.  *    as ---    cross assembler main program
  50.  */
  51. main(argc,argv)
  52. int    argc;
  53. char    **argv;
  54. {
  55.     char    **np;
  56.     char    *i;
  57.     FILE    *fopen();
  58.     int    j = 0;
  59.  
  60.     if(argc < 2){
  61.         printf("Usage: %s [files]\n",argv[j]);
  62.         exit(1);
  63.         }
  64.       Argv = argv;
  65.       initialize();
  66.       while ((*argv[j] != '-') && (j<argc))
  67.        j++;
  68.       N_files = j-1;
  69.      if (j < argc )
  70.       {
  71.       argv[j]++;
  72.       while (j<argc)
  73.        {
  74.        for (i = argv[j]; *i != 0; i++)
  75.          if ((*i <= 'Z') && (*i >= 'A'))
  76.            *i = *i + 32;
  77.        if (strcmp(argv[j],"l")==0)
  78.          Lflag = 1;
  79.        else if (strcmp(argv[j],"nol")==0)
  80.          Lflag = 0;
  81.        else if (strcmp(argv[j],"c")==0)
  82.           Cflag = 1;
  83.        else if (strcmp(argv[j],"noc")==0)
  84.          Cflag = 0;
  85.        else if (strcmp(argv[j],"s")==0)
  86.          Sflag = 1;
  87.        else if (strcmp(argv[j],"cre")==0)
  88.          CREflag = 1;
  89.         j++;
  90.        }
  91.       }
  92.     root = NULL;
  93.  
  94.     Cfn = 0;
  95.     np = argv;
  96.     Line_num = 0; /* reset line number */
  97.     while( ++Cfn <= N_files )
  98.         if((Fd = fopen(*++np,"r")) == NULL)
  99.             printf("as: can't open %s\n",*np);
  100.         else{
  101.             make_pass();
  102.             fclose(Fd);
  103.         }
  104.     if( Err_count == 0 ){
  105.         Pass++;
  106.         re_init();
  107.         Cfn = 0;
  108.         np = argv;
  109.         Line_num = 0;
  110.         while( ++Cfn <= N_files)
  111.             if((Fd = fopen(*++np,"r")) != NULL)
  112.                 {
  113.                 make_pass();
  114.                 fclose(Fd);
  115.                  }
  116.             if (Sflag == 1)
  117.               {
  118.                 printf ("\f");
  119.                 stable (root);
  120.               }
  121.             if (CREflag == 1)
  122.               {
  123.                 printf ("\f");
  124.                 cross (root);
  125.               }
  126.         fprintf(Objfil,"S9030000FC\r\n"); /* at least give a decent ending */
  127.         }
  128.     exit(Err_count);
  129. }
  130.  
  131. initialize()
  132. {
  133.     FILE    *fopen();
  134.     int    i = 0;
  135.  
  136. #ifdef DEBUG
  137.     printf("Initializing\n");
  138. #endif
  139.     Err_count = 0;
  140.     Pc      = 0;
  141.     Pass      = 1;
  142.     Lflag      = 0;
  143.     Cflag      = 0;
  144.     Ctotal      = 0;
  145.     Sflag      = 0;
  146.     CREflag   = 0;
  147.     N_page      = 0;
  148.     Line[MAXBUF-1] = NEWLINE;
  149.  
  150.     strcpy(Obj_name,Argv[1]); /* copy first file name into array */
  151.     do {
  152.         if (Obj_name[i]=='.')
  153.            Obj_name[i]=0;
  154.     }
  155.     while (Obj_name[i++] != 0);
  156.     strcat(Obj_name,".s19");  /* append .out to file name. */
  157.     if( (Objfil = fopen(Obj_name,"w")) == NULL)
  158.         fatal("Can't create object file");
  159.     fwdinit();    /* forward ref init */
  160.     localinit();    /* target machine specific init. */
  161. }
  162.  
  163. re_init()
  164. {
  165. #ifdef DEBUG
  166.     printf("Reinitializing\n");
  167. #endif
  168.     Pc    = 0;
  169.     E_total = 0;
  170.     P_total = 0;
  171.     Ctotal    = 0;
  172.     N_page    = 0;
  173.     fwdreinit();
  174. }
  175.  
  176. make_pass()
  177. {
  178.     char    *fgets();
  179.  
  180. #ifdef DEBUG
  181.     printf("Pass %d\n",Pass);
  182. #endif
  183.     while( fgets(Line,MAXBUF-1,Fd) != (char *)NULL ){
  184.         Line_num++;
  185.         P_force = 0;    /* No force unless bytes emitted */
  186.         N_page = 0;
  187.            if(parse_line())
  188.             process();
  189.         if(Pass == 2 && Lflag && !N_page)
  190.             print_line();
  191.         P_total = 0;    /* reset byte count */
  192.         Cycles = 0;    /* and per instruction cycle count */
  193.         }
  194.     f_record();
  195. }
  196.  
  197.  
  198. /*
  199.  *    parse_line --- split input line into label, op and operand
  200.  */
  201. parse_line()
  202. {
  203.     register char *ptrfrm = Line;
  204.     register char *ptrto = Label;
  205.     char    *skip_white();
  206.  
  207.     if( *ptrfrm == '*' || *ptrfrm == '\n' )
  208.         return(0);    /* a comment line */
  209.  
  210.     while( delim(*ptrfrm)== NO )
  211.         *ptrto++ = *ptrfrm++;
  212.     if(*--ptrto != ':')ptrto++;     /* allow trailing : */
  213.     *ptrto = EOS;
  214.  
  215.     ptrfrm = skip_white(ptrfrm);
  216.  
  217.     ptrto = Op;
  218.     while( delim(*ptrfrm) == NO)
  219.         *ptrto++ = mapdn(*ptrfrm++);
  220.     *ptrto = EOS;
  221.  
  222.     ptrfrm = skip_white(ptrfrm);
  223.  
  224.     ptrto = Operand;
  225.     while( *ptrfrm != NEWLINE )
  226.         *ptrto++ = *ptrfrm++;
  227.     *ptrto = EOS;
  228.  
  229. #ifdef DEBUG
  230.     printf("Label-%s-\n",Label);
  231.     printf("Op----%s-\n",Op);
  232.     printf("Operand-%s-\n",Operand);
  233. #endif
  234.     return(1);
  235. }
  236.  
  237. /*
  238.  *    process --- determine mnemonic class and act on it
  239.  */
  240. process()
  241. {
  242.     register struct oper *i;
  243.     struct oper *mne_look();
  244.  
  245.     Old_pc = Pc;        /* setup `old' program counter */
  246.     Optr = Operand;     /* point to beginning of operand field */
  247.  
  248.     if(*Op==EOS){        /* no mnemonic */
  249.         if(*Label != EOS)
  250.             install(Label,Pc);
  251.         }
  252.     else if( (i = mne_look(Op))== NULL)
  253.         error("Unrecognized Mnemonic");
  254.     else if( i->class == PSEUDO )
  255.         do_pseudo(i->opcode);
  256.     else{
  257.         if( *Label )install(Label,Pc);
  258.         if(Cflag)Cycles = i->cycles;
  259.         do_op(i->opcode,i->class);
  260.         if(Cflag)Ctotal += Cycles;
  261.         }
  262. }
  263. SHAR_EOF
  264. cat << \SHAR_EOF > AS.H
  265. /*
  266.  *      machine independent definitions and global variables
  267.  */
  268.  
  269. #define YES     1
  270. #define NO      0
  271. #define ERR     (-1)
  272.  
  273. #define MAXBUF  128
  274. #define MAXOP   10      /* longest mnemonic */
  275. #define MAXLAB  16
  276. #define E_LIMIT 32
  277. #define P_LIMIT 64
  278.  
  279. /*      Character Constants     */
  280. #define NEWLINE '\n'
  281. #define TAB     '\t'
  282. #define BLANK   ' '
  283. #define EOS     '\0'
  284.  
  285. /*      Opcode Classes          */
  286. #define INH     0       /* Inherent                     */
  287. #define GEN     1       /* General Addressing           */
  288. #define IMM     2       /* Immediate only               */
  289. #define REL     3       /* Short Relative               */
  290. #define P2REL   4       /* Long Relative                */
  291. #define P1REL   5       /* Long Relative (LBRA and LBSR)*/
  292. #define NOIMM   6       /* General except for Immediate */
  293. #define P2GEN   7       /* Page 2 General               */
  294. #define P3GEN   8       /* Page 3 General               */
  295. #define RTOR    9       /* Register To Register         */
  296. #define INDEXED 10      /* Indexed only                 */
  297. #define RLIST   11      /* Register List                */
  298. #define P2NOIMM 12      /* Page 2 No Immediate          */
  299. #define P2INH   13      /* Page 2 Inherent              */
  300. #define P3INH   14      /* Page 3 Inherent              */
  301. #define GRP2    15      /* Group 2 (Read/Modify/Write)  */
  302. #define LONGIMM 16      /* Immediate mode takes 2 bytes */
  303. #define BTB     17      /* Bit test and branch          */
  304. #define SETCLR  18      /* Bit set or clear             */
  305. #define CPD     19      /* compare d               6811 */
  306. #define XLIMM   20      /* LONGIMM for X           6811 */
  307. #define XNOIMM  21      /* NOIMM for X             6811 */
  308. #define YLIMM   22      /* LONGIMM for Y           6811 */
  309. #define YNOIMM  23      /* NOIMM for Y             6811 */
  310. #define FAKE    24      /* convenience mnemonics   6804 */
  311. #define APOST   25      /* A accum after opcode    6804 */
  312. #define BPM     26      /* branch reg plus/minus   6804 */
  313. #define CLRX    27      /* mvi x,0                 6804 */
  314. #define CLRY    28      /* mvi y,0                 6804 */
  315. #define LDX     29      /* mvi x,expr              6804 */
  316. #define LDY     30      /* mvi y,expr              6804 */
  317. #define MVI     31      /* mvi                     6804 */
  318. #define EXT     32      /* extended                6804 */
  319. #define BIT     33      /* bit manipulation        6301 */
  320. #define SYS     34      /* syscalls (really swi)        */
  321. #define PSEUDO  35      /* Pseudo ops                   */
  322.  
  323. /* global variables */
  324. int     Line_num =0;            /* current line number          */
  325. int     Err_count =0;           /* total number of errors       */
  326. char    Line[MAXBUF] = {0};     /* input line buffer            */
  327. char    Label[MAXLAB] = {0};    /* label on current line        */
  328. char    Op[MAXOP] = {0};        /* opcode mnemonic on current line      */
  329. char    Operand[MAXBUF] = {0};  /* remainder of line after op           */
  330. char    *Optr =0;               /* pointer into current Operand field   */
  331. int     Result =0;              /* result of expression evaluation      */
  332. int     Force_word =0;          /* Result should be a word when set     */
  333. int     Force_byte =0;          /* Result should be a byte when set     */
  334. int     Pc =0;                  /* Program Counter              */
  335. int     Old_pc =0;              /* Program Counter at beginning */
  336.  
  337. int     Last_sym =0;            /* result of last lookup        */
  338.  
  339. int     Pass =0;                /* Current pass #               */
  340. int     N_files =0;             /* Number of files to assemble  */
  341. FILE    *Fd =0;                 /* Current input file structure */
  342. int     Cfn =0;                 /* Current file number 1...n    */
  343. int     Ffn =0;                 /* forward ref file #           */
  344. int     F_ref =0;               /* next line with forward ref   */
  345. char    **Argv =0;              /* pointer to file names        */
  346.  
  347. int     E_total =0;             /* total # bytes for one line   */
  348. int     E_bytes[E_LIMIT] = {0}; /* Emitted held bytes           */
  349. int     E_pc =0;                /* Pc at beginning of collection*/
  350.  
  351. int     Lflag = 0;              /* listing flag 0=nolist, 1=list*/
  352.  
  353. int     P_force = 0;            /* force listing line to include Old_pc */
  354. int     P_total =0;             /* current number of bytes collected    */
  355. int     P_bytes[P_LIMIT] = {0}; /* Bytes collected for listing  */
  356.  
  357. int     Cflag = 0;              /* cycle count flag */
  358. int     Cycles = 0;             /* # of cycles per instruction  */
  359. long    Ctotal = 0;             /* # of cycles seen so far */
  360. int     Sflag = 0;              /* symbol table flag, 0=no symbol */
  361. int     N_page = 0;             /* new page flag */
  362. int     Page_num = 2;           /* page number */
  363. int     CREflag = 0;            /* cross reference table flag */
  364.  
  365. struct link { /* linked list to hold line numbers */
  366.        int L_num; /* line number */
  367.        struct link *next; /* pointer to next node */
  368. };
  369.  
  370. struct nlist { /* basic symbol table entry */
  371.         char    *name;
  372.         int     def;
  373.         struct nlist *Lnext ; /* left node of the tree leaf */
  374.         struct nlist *Rnext; /* right node of the tree leaf */ 
  375.         struct link *L_list; /* pointer to linked list of line numbers */
  376. };
  377.  
  378. struct oper {   /* an entry in the mnemonic table */
  379.         char    *mnemonic;      /* its name */
  380.         char    class;          /* its class */
  381.         int     opcode;         /* its base opcode */
  382.         char    cycles;         /* its base # of cycles */
  383. };
  384.  
  385. struct  nlist *root;            /* root node of the tree */
  386.   
  387. FILE    *Objfil =0;             /* object file's file descriptor*/
  388. char    Obj_name[] = {"             "};
  389. SHAR_EOF
  390. cat << \SHAR_EOF > AS0.C
  391. #include <stdio.h>
  392. #include "as.h"
  393. #include "table0.h"
  394. #include "as.c"
  395. #include "do0.c"
  396. #include "pseudo.c"
  397. #include "eval.c"
  398. #include "symtab.c"
  399. #include "util.c"
  400. #include "ffwd.c"
  401. #include "output.c"
  402. SHAR_EOF
  403. cat << \SHAR_EOF > AS1.C
  404. #include <stdio.h>
  405. #include "as.h"
  406. #include "table1.h"
  407. #include "as.c"
  408. #include "do1.c"
  409. #include "pseudo.c"
  410. #include "eval.c"
  411. #include "symtab.c"
  412. #include "util.c"
  413. #include "ffwd.c"
  414. #include "output.c"
  415.  
  416. SHAR_EOF
  417. cat << \SHAR_EOF > AS11.C
  418. #include <stdio.h>
  419. #include "as.h"
  420. #include "table11.h"
  421. #include "as.c"
  422. #include "do11.c"
  423. #include "pseudo.c"
  424. #include "eval.c"
  425. #include "symtab.c"
  426. #include "util.c"
  427. #include "ffwd.c"
  428. #include "output.c"
  429. SHAR_EOF
  430. cat << \SHAR_EOF > AS4.C
  431. #include <stdio.h>
  432. #include "as.h"
  433. #include "table4.h"
  434. #include "as.c"
  435. #include "do4.c"
  436. #include "pseudo.c"
  437. #include "eval.c"
  438. #include "symtab.c"
  439. #include "util.c"
  440. #include "ffwd.c"
  441. #include "output.c"
  442. SHAR_EOF
  443. cat << \SHAR_EOF > AS5.C
  444. #include <stdio.h>
  445. #include "as.h"
  446. #include "table5.h"
  447. #include "as.c"
  448. #include "do5.c"
  449. #include "pseudo.c"
  450. #include "eval.c"
  451. #include "symtab.c"
  452. #include "util.c"
  453. #include "ffwd.c"
  454. #include "output.c"
  455.  
  456. SHAR_EOF
  457. cat << \SHAR_EOF > AS9.C
  458. #include <stdio.h>
  459. #include "as.h"
  460. #include "table9.h"
  461. #include "as.c"
  462. #include "do9.c"
  463. #include "pseudo.c"
  464. #include "eval.c"
  465. #include "symtab.c"
  466. #include "util.c"
  467. #include "ffwd.c"
  468. #include "output.c"
  469.  
  470. SHAR_EOF
  471. cat << \SHAR_EOF > DO0.C
  472. /*
  473.  *    MC6800/02 specific processing
  474.  */
  475.  
  476. /* addressing modes */
  477. #define IMMED    0    /* immediate */
  478. #define IND    1    /* indexed */
  479. #define OTHER    2    /* NOTA */
  480.  
  481. /*
  482.  *    localinit --- machine specific initialization
  483.  */
  484. localinit()
  485. {
  486. }
  487.  
  488. /*
  489.  *    do_op --- process mnemonic
  490.  *
  491.  *    Called with the base opcode and it's class. Optr points to
  492.  *    the beginning of the operand field.
  493.  */
  494. do_op(opcode,class)
  495. int opcode;    /* base opcode */
  496. int class;    /* mnemonic class */
  497. {
  498.     int    dist;    /* relative branch distance */
  499.     int    amode;    /* indicated addressing mode */
  500.     char    *peek;
  501.  
  502.     /* guess at addressing mode */
  503.     peek = Optr;
  504.     amode = OTHER;
  505.     while( !delim(*peek) && *peek != EOS)  /* check for comma in operand field */
  506.         if( *peek++ == ',' ){
  507.             amode = IND;
  508.             break;
  509.             }
  510.     if( *Optr == '#' ) amode = IMMED;
  511.  
  512.     switch(class){
  513.         case INH:            /* inherent addressing */
  514.             emit(opcode);
  515.             return;
  516.         case GEN:            /* general addressing */
  517.             do_gen(opcode,amode);
  518.             return;
  519.         case REL:            /* relative branches */
  520.             eval();
  521.             dist = Result - (Pc+2);
  522.             emit(opcode);
  523.             if( (dist >127 || dist <-128) && Pass==2){
  524.                 error("Branch out of Range");
  525.                 emit(lobyte(-2));
  526.                 return;
  527.                 }
  528.             emit(lobyte(dist));
  529.             return;
  530.         case NOIMM:
  531.             if( amode == IMMED){
  532.                 error("Immediate Addressing Illegal");
  533.                 return;
  534.                 }
  535.             if((opcode == 0x8D) && (amode == IND)){
  536.                 Cycles-=2;
  537.                 }
  538.             do_gen(opcode,amode);
  539.  
  540.             return;
  541.         case LONGIMM:
  542.             if( amode == IMMED ){
  543.                 emit(opcode);
  544.                 Optr++;
  545.                 eval();
  546.                 eword(Result);
  547.                 return;
  548.                 }
  549.             do_gen(opcode,amode);
  550.             return;
  551.         case GRP2:
  552.             if( amode == IND ){
  553.                 Cycles++;
  554.                 do_indexed(opcode);
  555.                 return;
  556.                 }
  557.             /* extended addressing */
  558.             eval();
  559.             emit(opcode+0x10);
  560.             eword(Result);
  561.             return;
  562.         default:
  563.             fatal("Error in Mnemonic table");
  564.         }
  565. }
  566.  
  567. /*
  568.  *    do_gen --- process general addressing modes
  569.  */
  570. do_gen(op,mode)
  571. int    op;
  572. int    mode;
  573. {
  574.     if( mode == IMMED){
  575.         Optr++;
  576.         emit(op);
  577.         eval();
  578.         emit(lobyte(Result));
  579.         return;
  580.         }
  581.     else if( mode == IND ){
  582.         Cycles+=3;
  583.         do_indexed(op+0x20);
  584.         return;
  585.         }
  586.     else if( mode == OTHER){
  587.         eval();
  588.         if(Force_word){
  589.             emit(op+0x30);
  590.             eword(Result);
  591.             Cycles+=2;
  592.             return;
  593.             }
  594.         if(Force_byte){
  595.             emit(op+0x10);
  596.             emit(lobyte(Result));
  597.             Cycles++;
  598.             return;
  599.             }
  600.         if(Result>=0 && Result <=0xFF){
  601.             emit(op+0x10);
  602.             emit(lobyte(Result));
  603.             Cycles++;
  604.             return;
  605.             }
  606.         else {
  607.             emit(op+0x30);
  608.             eword(Result);
  609.             Cycles+=2;
  610.             return;
  611.             }
  612.         }
  613.     else {
  614.         error("Unknown Addressing Mode");
  615.         return;
  616.         }
  617. }
  618.  
  619. /*
  620.  *    do_indexed --- handle all wierd stuff for indexed addressing
  621.  */
  622. do_indexed(op)
  623. int op;
  624. {
  625.     emit(op);
  626.     eval();
  627.     if( mapdn(*++Optr) != 'x' )
  628.         warn("Indexed Addressing Assumed");
  629.     if( Result < 0 || Result > 255)
  630.         warn("Value Truncated");
  631.     emit(lobyte(Result));
  632. }
  633. SHAR_EOF
  634. cat << \SHAR_EOF > DO1.C
  635. /*
  636.  *      MC6801 specific processing
  637.  */
  638.  
  639. /* addressing modes */
  640. #define IMMED   0       /* immediate */
  641. #define IND     1       /* indexed */
  642. #define OTHER   2       /* NOTA */
  643.  
  644. /*
  645.  *      localinit --- machine specific initialization
  646.  */
  647. localinit()
  648. {
  649. }
  650.  
  651. /*
  652.  *      do_op --- process mnemonic
  653.  *
  654.  *    Called with the base opcode and it's class. Optr points to
  655.  *    the beginning of the operand field.
  656.  */
  657. do_op(opcode,class)
  658. int opcode;    /* base opcode */
  659. int class;    /* mnemonic class */
  660. {
  661.     int     dist;   /* relative branch distance */
  662.     int     amode;  /* indicated addressing mode */
  663.     char    *peek;
  664.  
  665.     /* guess at addressing mode */
  666.     peek = Optr;
  667.     amode = OTHER;
  668.     while( !delim(*peek) && *peek != EOS)  /* check for comma in operand field */
  669.         if( *peek++ == ',' ){
  670.             amode = IND;
  671.             break;
  672.             }
  673.     if( *Optr == '#' ) amode = IMMED;
  674.  
  675.     switch(class){
  676.         case INH:                       /* inherent addressing */
  677.             emit(opcode);
  678.             return;
  679.         case GEN:                       /* general addressing */
  680.             do_gen(opcode,amode);
  681.             return;
  682.         case REL:                       /* relative branches */
  683.             eval();
  684.             dist = Result - (Pc+2);
  685.             emit(opcode);
  686.             if( (dist >127 || dist <-128) && Pass==2){
  687.                 error("Branch out of Range");
  688.                 emit(lobyte(-2));
  689.                 return;
  690.                 }
  691.             emit(lobyte(dist));
  692.             return;
  693.         case NOIMM:
  694.             if( amode == IMMED){
  695.                 error("Immediate Addressing Illegal");
  696.                 return;
  697.                 }
  698.             do_gen(opcode,amode);
  699.             return;
  700.         case LONGIMM:
  701.             if( amode == IMMED ){
  702.                 emit(opcode);
  703.                 Optr++;
  704.                 eval();
  705.                 eword(Result);
  706.                 return;
  707.                 }
  708.             do_gen(opcode,amode);
  709.             return;
  710.         case GRP2:
  711.             if( amode == IND ){
  712.                 do_indexed(opcode);
  713.                 return;
  714.                 }
  715.             /* extended addressing */
  716.             eval();
  717.             emit(opcode+0x10);
  718.             eword(Result);
  719.             return;
  720.         default:
  721.             fatal("Error in Mnemonic table");
  722.         }
  723. }
  724.  
  725. /*
  726.  *      do_gen --- process general addressing modes
  727.  */
  728. do_gen(op,mode)
  729. int     op;
  730. int     mode;
  731. {
  732.     if( mode == IMMED){
  733.         Optr++;
  734.         emit(op);
  735.         eval();
  736.         emit(lobyte(Result));
  737.         return;
  738.         }
  739.     else if( mode == IND ){
  740.         Cycles+=2;
  741.         do_indexed(op+0x20);
  742.         return;
  743.         }
  744.     else if( mode == OTHER){
  745.         eval();
  746.         if(Force_word){
  747.             emit(op+0x30);
  748.             eword(Result);
  749.             Cycles+=2;
  750.             return;
  751.             }
  752.         if(Force_byte){
  753.             emit(op+0x10);
  754.             emit(lobyte(Result));
  755.             Cycles++;
  756.             return;
  757.             }
  758.         if(Result>=0 && Result <=0xFF){
  759.             emit(op+0x10);
  760.             emit(lobyte(Result));
  761.             Cycles++;
  762.             return;
  763.             }
  764.         else {
  765.             emit(op+0x30);
  766.             eword(Result);
  767.             Cycles+=2;
  768.             return;
  769.             }
  770.         }
  771.     else {
  772.         error("Unknown Addressing Mode");
  773.         return;
  774.         }
  775. }
  776.  
  777. /*
  778.  *      do_indexed --- handle all wierd stuff for indexed addressing
  779.  */
  780. do_indexed(op)
  781. int op;
  782. {
  783.     emit(op);
  784.     eval();
  785.     if( mapdn(*++Optr) != 'x' )
  786.         warn("Indexed Addressing Assumed");
  787.     if( Result < 0 || Result > 255)
  788.         warn("Value Truncated");
  789.     emit(lobyte(Result));
  790. }
  791. SHAR_EOF
  792. cat << \SHAR_EOF > DO11.C
  793. /*
  794.  *      MC68HC11 specific processing
  795.  */
  796.  
  797. #define PAGE1   0x00
  798. #define PAGE2   0x18
  799. #define PAGE3   0x1A
  800. #define PAGE4   0xCD
  801.  
  802. /* addressing modes */
  803. #define IMMED   0
  804. #define INDX    1
  805. #define INDY    2
  806. #define LIMMED  3       /* long immediate */
  807. #define OTHER   4
  808.  
  809. int     yflag = 0;      /* YNOIMM, YLIMM, and CPD flag */
  810.  
  811. /*
  812.  *      localinit --- machine specific initialization
  813.  */
  814. localinit()
  815. {
  816. }
  817.  
  818. /*
  819.  *      do_op --- process mnemonic
  820.  *
  821.  *    Called with the base opcode and it's class. Optr points to
  822.  *    the beginning of the operand field.
  823.  */
  824. do_op(opcode,class)
  825. int opcode;    /* base opcode */
  826. int class;    /* mnemonic class */
  827. {
  828.     int     dist;   /* relative branch distance */
  829.     int     amode;  /* indicated addressing mode */
  830.     char    *peek;
  831.  
  832.     /* guess at addressing mode */
  833.     peek = Optr;
  834.     amode = OTHER;
  835.     while( !delim(*peek) && *peek != EOS)  /* check for comma in operand field */
  836.         if( *peek++ == ',' ){
  837.             if( mapdn(*peek) == 'y' )
  838.                 amode = INDY;
  839.             else
  840.                 amode = INDX;
  841.             break;
  842.             }
  843.     if( *Optr == '#' ) amode = IMMED;
  844.  
  845.     yflag = 0;
  846.     switch(class){
  847.         case P2INH:
  848.             emit(PAGE2);
  849.         case INH:                       /* inherent addressing */
  850.             emit(opcode);
  851.             return;
  852.         case REL:                       /* relative branches */
  853.             eval();
  854.             dist = Result - (Pc+2);
  855.             emit(opcode);
  856.             if( (dist >127 || dist <-128) && Pass==2){
  857.                 error("Branch out of Range");
  858.                 emit(lobyte(-2));
  859.                 return;
  860.                 }
  861.             emit(lobyte(dist));
  862.             return;
  863.         case LONGIMM:
  864.             if( amode == IMMED )
  865.                 amode = LIMMED;
  866.         case NOIMM:
  867.             if( amode == IMMED ){
  868.                 error("Immediate Addressing Illegal");
  869.                 return;
  870.                 }
  871.         case GEN:                       /* general addressing */
  872.             do_gen(opcode,amode,PAGE1,PAGE1,PAGE2);
  873.             return;
  874.         case GRP2:
  875.             if( amode == INDY ){
  876.                 Cycles++;
  877.                 emit(PAGE2);
  878.                 amode = INDX;
  879.                 }
  880.             if( amode == INDX )
  881.                 do_indexed(opcode);
  882.             else{   /* extended addressing */
  883.                 eval();
  884.                 emit(opcode+0x10);
  885.                 eword(Result);
  886.                 }
  887.             return;
  888.         case CPD:               /* cmpd */
  889.             if( amode == IMMED )
  890.                 amode = LIMMED;
  891.             if( amode == INDY )
  892.                 yflag=1;
  893.             do_gen(opcode,amode,PAGE3,PAGE3,PAGE4);
  894.             return;
  895.         case XNOIMM:            /* stx */
  896.             if( amode == IMMED ){
  897.                 error("Immediate Addressing Illegal");
  898.                 return;
  899.                 }
  900.         case XLIMM:             /* cpx, ldx */
  901.             if( amode == IMMED )
  902.                 amode = LIMMED;
  903.             do_gen(opcode,amode,PAGE1,PAGE1,PAGE4);
  904.             return;
  905.         case YNOIMM:            /* sty */
  906.             if( amode == IMMED ){
  907.                 error("Immediate Addressing Illegal");
  908.                 return;
  909.                 }
  910.         case YLIMM:             /* cpy, ldy */
  911.             if(amode == INDY)
  912.                 yflag=1;
  913.             if( amode == IMMED )
  914.                 amode = LIMMED;
  915.             do_gen(opcode,amode,PAGE2,PAGE3,PAGE2);
  916.             return;
  917.         case BTB:               /* bset, bclr */
  918.         case SETCLR:            /* brset, brclr */
  919.             opcode = bitop(opcode,amode,class);
  920.  
  921.             if (amode == INDX)
  922.                 Cycles++;
  923.             if( amode == INDY ){
  924.                 Cycles+=2;
  925.                 emit(PAGE2);
  926.                 amode = INDX;
  927.                 }
  928.             emit(opcode);
  929.             eval();
  930.             emit(lobyte(Result));   /* address */
  931.             if( amode == INDX )
  932.                 Optr += 2;      /* skip ,x or ,y */
  933.             Optr = skip_white(Optr);
  934.             eval();
  935.             emit(lobyte(Result));   /* mask */
  936.             if( class == SETCLR )
  937.                 return;
  938.             Optr = skip_white(Optr);
  939.             eval();
  940.             dist = Result - (Pc+1);
  941.             if( (dist >127 || dist <-128) && Pass==2){
  942.                 error("Branch out of Range");
  943.                 dist = Old_pc - (Pc+1);
  944.                 }
  945.             emit(lobyte(dist));
  946.             return;
  947.         default:
  948.             fatal("Error in Mnemonic table");
  949.         }
  950. }
  951.  
  952. /*
  953.  *      bitop --- adjust opcode on bit manipulation instructions
  954.  */
  955. bitop(op,mode,class)
  956. int op;
  957. int mode;
  958. int class;
  959. {
  960.     if( mode == INDX || mode == INDY )
  961.         return(op);
  962.     if( class == SETCLR )
  963.         return(op-8);
  964.     else if(class==BTB)
  965.         return(op-12);
  966.     else
  967.         fatal("bitop");
  968. }
  969.  
  970. /*
  971.  *      do_gen --- process general addressing modes
  972.  */
  973. do_gen(op,mode,pnorm,px,py)
  974. int     op;     /* base opcode */
  975. int     mode;   /* addressing mode */
  976. int     pnorm;  /* page for normal addressing modes: IMM,DIR,EXT */
  977. int     px;     /* page for INDX addressing */
  978. int     py;     /* page for INDY addressing */
  979. {
  980.     switch(mode){
  981.     case LIMMED:
  982.         Optr++;
  983.         epage(pnorm);
  984.         emit(op);
  985.         eval();
  986.         eword(Result);
  987.         break;
  988.     case IMMED:
  989.         Optr++;
  990.         epage(pnorm);
  991.         emit(op);
  992.         eval();
  993.         emit(lobyte(Result));
  994.         break;
  995.     case INDY:
  996.         if(yflag)
  997.             Cycles += 2;
  998.         else
  999.             Cycles += 3;
  1000.         epage(py);
  1001.         do_indexed(op+0x20);
  1002.         break;
  1003.     case INDX:
  1004.         Cycles+=2;
  1005.         epage(px);
  1006.         do_indexed(op+0x20);
  1007.         break;
  1008.     case OTHER:
  1009.         eval();
  1010.         epage(pnorm);
  1011.         if(Force_word){
  1012.             emit(op+0x30);
  1013.             eword(Result);
  1014.             Cycles+=2;
  1015.             break;
  1016.             }
  1017.         if(Force_byte){
  1018.             emit(op+0x10);
  1019.             emit(lobyte(Result));
  1020.             Cycles++;
  1021.             break;
  1022.             }
  1023.         if(Result>=0 && Result <=0xFF){
  1024.             emit(op+0x10);
  1025.             emit(lobyte(Result));
  1026.             Cycles++;
  1027.             break;
  1028.             }
  1029.         else {
  1030.             emit(op+0x30);
  1031.             eword(Result);
  1032.             Cycles+=2;
  1033.             break;
  1034.             }
  1035.         break;
  1036.     default:
  1037.         error("Unknown Addressing Mode");
  1038.     }
  1039. }
  1040.  
  1041. /*
  1042.  *      do_indexed --- handle all wierd stuff for indexed addressing
  1043.  */
  1044. do_indexed(op)
  1045. int op;
  1046. {
  1047.     char c;
  1048.  
  1049.     emit(op);
  1050.     eval();
  1051.     if( *Optr++ != ',' )
  1052.         error("Syntax");
  1053.     c = mapdn(*Optr++);
  1054.     if( c != 'x' && c != 'y')
  1055.         warn("Indexed Addressing Assumed");
  1056.     if( Result < 0 || Result > 255)
  1057.         warn("Value Truncated");
  1058.     emit(lobyte(Result));
  1059. }
  1060.  
  1061. /*
  1062.  *      epage --- emit page prebyte
  1063.  */
  1064. epage(p)
  1065. int p;
  1066. {
  1067.     if( p != PAGE1 )        /* PAGE1 means no prebyte */
  1068.         emit(p);
  1069. }
  1070. SHAR_EOF
  1071. cat << \SHAR_EOF > DO4.C
  1072. /*
  1073.  *      MC6804 specific processing
  1074.  */
  1075.  
  1076. #define IMMED   0
  1077. #define IND     1
  1078. #define OTHER   2
  1079.  
  1080. /* special addresses */
  1081. #define XREG    0x80
  1082. #define YREG    0x81
  1083. #define SD1REG  0x82
  1084. #define SD2REG  0x83
  1085. #define ACCUM   0xFF
  1086.  
  1087. /*
  1088.  *      localinit --- machine specific initialization
  1089.  */
  1090. localinit()
  1091. {
  1092.     install("x",XREG);
  1093.     install("X",XREG);
  1094.     install("y",YREG);
  1095.     install("Y",YREG);
  1096.     install("a",ACCUM);
  1097.     install("A",ACCUM);
  1098. }
  1099.  
  1100. /*
  1101.  *      do_op --- process mnemonic
  1102.  */
  1103. do_op(opcode,class)
  1104. {
  1105.     int     dist;   /* relative branch distance */
  1106.     int     amode;  /* indicated addressing mode */
  1107.     int     r1;     /* first eval() for mvi */
  1108.  
  1109.     if (( *Operand == '[' ) || ( *Operand == ','))
  1110.         amode = IND;
  1111.     else if( *Operand == '#' )
  1112.         amode = IMMED;
  1113.     else
  1114.         amode = OTHER;
  1115.  
  1116.     switch(class){
  1117.         case INH:                       /* inherent addressing */
  1118.             emit(opcode);
  1119.             return;
  1120.         case APOST:             /* A address in mem follows opcode */
  1121.             emit(opcode);
  1122.             emit(ACCUM);
  1123.             return;
  1124.         case REL:                       /* short relative branches */
  1125.             eval();
  1126.             dist = Result - (Pc+1);
  1127.             if( (dist >15 || dist <-16) && Pass==2){
  1128.                 error("Branch out of Range");
  1129.                 dist = -1;
  1130.                 }
  1131.             emit(opcode + (dist&0x1F));
  1132.             return;
  1133.         case BTB:
  1134.         case SETCLR:
  1135.             eval();
  1136.             if(Result <0 || Result >7){
  1137.                 error("Bit Number must be 0-7");
  1138.                 return;
  1139.                 }
  1140.             emit( opcode + Result);
  1141.             if(*Optr++ != ',')error("SYNTAX");
  1142.             eval();
  1143.             emit(lobyte(Result));
  1144.             if( class == SETCLR )
  1145.                 return;
  1146.             if(*Optr++ != ',')error("SYNTAX");
  1147.             eval();
  1148.             dist = Result - (Old_pc+3);
  1149.             if( (dist >127 || dist <-128) && Pass==2){
  1150.                 error("Branch out of Range");
  1151.                 dist = -3;
  1152.                 return;
  1153.                 }
  1154.             emit(lobyte(dist));
  1155.             return;
  1156.         case EXT:               /* jsr, jmp */
  1157.             eval();
  1158.             emit(opcode | (hibyte(Result) & 0x0F));
  1159.             emit(lobyte(Result));
  1160.             return;
  1161.         case BPM:       /* brset/clr 7,accum,target */
  1162.             emit(opcode);
  1163.             emit(ACCUM);
  1164.             eval();
  1165.             dist = Result - (Old_pc + 3);
  1166.             if ((dist > 127 || dist < -128) && Pass == 2) {
  1167.                 error("Branch out of range");
  1168.                 dist = -3;
  1169.                 return;
  1170.                 }
  1171.             emit(lobyte(dist));
  1172.             return;
  1173.         case MVI:
  1174.             eval();
  1175.             r1 = Result;    /* save result */
  1176.             if (*Optr++ != ',')
  1177.                 warn("Missing ','");
  1178.             eval();
  1179.             mvi(opcode,r1,Result);
  1180.             return;
  1181.         case CLRX:      /* mvi xreg,0 */
  1182.             mvi(opcode,XREG,0);
  1183.             return;
  1184.         case CLRY:      /* mvi yreg,0 */
  1185.             mvi(opcode,YREG,0);
  1186.             return;
  1187.         case LDX:       /* mvi xreg data */
  1188.             if (amode == IMMED) Optr++;
  1189.             eval();
  1190.             mvi(opcode,XREG,Result);
  1191.             return;
  1192.         case LDY:       /* mvi yreg data */
  1193.             if (amode == IMMED) Optr++;
  1194.             eval();
  1195.             mvi(opcode,YREG,Result);
  1196.             return;
  1197.         case NOIMM:
  1198.             if( amode == IMMED ){
  1199.                 error("Immediate Addressing Illegal");
  1200.                 return;
  1201.                 }
  1202.         case GEN:
  1203.             if ( amode == IMMED ) {
  1204.                 Optr++;
  1205.                 eval();
  1206.                 emit(opcode | 0x08);
  1207.                 emit(Result);
  1208.                 return;
  1209.                 }
  1210.             if( amode == IND ){
  1211.                 Optr++;
  1212.                 eval();
  1213.                 if ((*Optr != ']') && (*Operand != ','))
  1214.                     warn("Missing ']'");
  1215.                 if (Result != XREG && Result != YREG) {
  1216.                     error("Operand must be $80 or $81");
  1217.                     emit(opcode);
  1218.                     return;
  1219.                 }
  1220.                 emit(opcode | ((Result&0x01)<<4));
  1221.                 return;
  1222.                 }
  1223.             eval();
  1224.             if (XREG <= Result && Result <=SD2REG){
  1225.                 /*check for short direct cases*/
  1226.                 if ( opcode==0xE6 ) {   /* inc */
  1227.                     emit(0xA8 + (Result-XREG));
  1228.                     return;
  1229.                     }
  1230.                 if ( opcode==0xE7 ) { /* dec */
  1231.                     emit(0xB8 + (Result-XREG));
  1232.                     return;
  1233.                     }
  1234.                 if ( opcode==0xE0 ) { /* lda */
  1235.                     emit(0xAC | (Result-XREG));
  1236.                     return;
  1237.                     }
  1238.                 if ( opcode==0xE1 ) { /* sta */
  1239.                     emit(0xBC | (Result-XREG));
  1240.                     return;
  1241.                     }
  1242.                 }
  1243.             /* else direct addressing */
  1244.             emit( opcode | 0x18);
  1245.             emit(lobyte(Result));
  1246.             return;
  1247.         default:
  1248.             fatal("Error in Mnemonic table");
  1249.         }
  1250. }
  1251.  
  1252. mvi(op,to,from)
  1253. int op,to,from;
  1254. {
  1255.     emit(op);
  1256.     emit(to);
  1257.     emit(from);
  1258. }
  1259. SHAR_EOF
  1260. cat << \SHAR_EOF > DO5.C
  1261. /*
  1262.  *      MC6805 specific processing
  1263.  */
  1264.  
  1265. /* addressing modes */
  1266. #define IMMED   0       /* immediate */
  1267. #define IND     1       /* indexed */
  1268. #define OTHER   2       /* NOTA */
  1269.  
  1270. /*
  1271.  *      localinit --- machine specific initialization
  1272.  */
  1273. localinit()
  1274. {
  1275. }
  1276.  
  1277. /*
  1278.  *      do_op --- process mnemonic
  1279.  *
  1280.  *    Called with the base opcode and it's class. Optr points to
  1281.  *    the beginning of the operand field.
  1282.  */
  1283. do_op(opcode,class)
  1284. int opcode;    /* base opcode */
  1285. int class;    /* mnemonic class */
  1286. {
  1287.     int     dist;   /* relative branch distance */
  1288.     int     amode;  /* indicated addressing mode */
  1289.     char    *peek;
  1290.  
  1291.     /* guess at addressing mode */
  1292.     peek = Optr;
  1293.     amode = OTHER;
  1294.     while( !delim(*peek) && *peek != EOS)  /* check for comma in operand field */
  1295.         if( *peek++ == ',' ){
  1296.             amode = IND;
  1297.             break;
  1298.             }
  1299.     if( *Optr == '#' ) amode = IMMED;
  1300.  
  1301.     switch(class){
  1302.         case INH:                       /* inherent addressing */
  1303.             emit(opcode);
  1304.             return;
  1305.         case GEN:                       /* general addressing */
  1306.             do_gen(opcode,amode);
  1307.             return;
  1308.         case REL:                       /* short relative branches */
  1309.             eval();
  1310.             dist = Result - (Pc+2);
  1311.             emit(opcode);
  1312.             if( (dist >127 || dist <-128) && Pass==2){
  1313.                 error("Branch out of Range");
  1314.                 emit(lobyte(-2));
  1315.                 return;
  1316.                 }
  1317.             emit(lobyte(dist));
  1318.             return;
  1319.         case NOIMM:
  1320.             if( amode == IMMED ){
  1321.                 error("Immediate Addressing Illegal");
  1322.                 return;
  1323.                 }
  1324.             do_gen(opcode,amode);
  1325.             return;
  1326.         case GRP2:
  1327.             if( amode == IND ){
  1328.                 do_indexed(opcode+0x20);
  1329.                 return;
  1330.                 }
  1331.             eval();
  1332.             Cycles += 2;
  1333.             if(Force_byte){
  1334.                 emit(opcode);
  1335.                 emit(lobyte(Result));
  1336.                 return;
  1337.                 }
  1338.             if(Result>=0 && Result <=0xFF){
  1339.                 emit(opcode);
  1340.                 emit(lobyte(Result));
  1341.                 return;
  1342.                 }
  1343.             error("Extended Addressing not allowed");
  1344.             return;
  1345.         case SETCLR:
  1346.         case BTB:
  1347.             eval();
  1348.             if(Result <0 || Result >7){
  1349.                 error("Bit Number must be 0-7");
  1350.                 return;
  1351.                 }
  1352.             emit( opcode | (Result << 1));
  1353.             if(*Optr++ != ',')error("SYNTAX");
  1354.             eval();
  1355.             emit(lobyte(Result));
  1356.             if(class==SETCLR)
  1357.                 return;
  1358.             /* else it's bit test and branch */
  1359.             if(*Optr++ != ',')error("SYNTAX");
  1360.             eval();
  1361.             dist = Result - (Old_pc+3);
  1362.             if( (dist >127 || dist <-128) && Pass==2){
  1363.                 error("Branch out of Range");
  1364.                 emit(lobyte(-3));
  1365.                 return;
  1366.                 }
  1367.             emit(lobyte(dist));
  1368.             return;
  1369.         default:
  1370.             fatal("Error in Mnemonic table");
  1371.         }
  1372. }
  1373.  
  1374. /*
  1375.  *      do_gen --- process general addressing
  1376.  */
  1377. do_gen(op,mode)
  1378. int     op;
  1379. int     mode;
  1380. {
  1381.     if( mode == IMMED){
  1382.         Optr++;
  1383.         emit(op);
  1384.         eval();
  1385.         emit(lobyte(Result));
  1386.         return;
  1387.         }
  1388.     else if( mode == IND ){
  1389.         do_indexed(op+0x30);
  1390.         return;
  1391.         }
  1392.     else if( mode == OTHER){        /* direct or extended addressing */
  1393.         eval();
  1394.         if(Force_word){
  1395.             emit(op+0x20);
  1396.             eword(Result);
  1397.             Cycles += 3;
  1398.             return;
  1399.             }
  1400.         if(Force_byte){
  1401.             emit(op+0x10);
  1402.             emit(lobyte(Result));
  1403.             Cycles += 2;
  1404.             return;
  1405.             }
  1406.         if(Result >= 0 && Result <= 0xFF){
  1407.             emit(op+0x10);
  1408.             emit(lobyte(Result));
  1409.             Cycles += 2;
  1410.             return;
  1411.             }
  1412.         else {
  1413.             emit(op+0x20);
  1414.             eword(Result);
  1415.             Cycles += 3;
  1416.             return;
  1417.             }
  1418.         }
  1419.     else {
  1420.         error("Unknown Addressing Mode");
  1421.         return;
  1422.         }
  1423. }
  1424.  
  1425. /*
  1426.  *      do_indexed --- handle all wierd stuff for indexed addressing
  1427.  */
  1428. do_indexed(op)
  1429. int op;
  1430. {
  1431.     eval();
  1432.     if(!(*Optr++ == ',' && (*Optr == 'x' || *Optr == 'X')))
  1433.         warn("Indexed Addressing Assumed");
  1434.     if(Force_word){
  1435.         if(op < 0x80 ){ /* group 2, no extended addressing */
  1436.             emit(op+0x10); /* default to one byte indexed */
  1437.             emit(lobyte(Result));
  1438.             Cycles += 3;
  1439.             return;
  1440.             }
  1441.         emit(op);
  1442.         eword(Result);
  1443.         Cycles += 4;
  1444.         return;
  1445.         }
  1446.     Cycles += 3;    /* assume 1 byte indexing */
  1447.     if(Force_byte){
  1448.         emit(op+0x10);
  1449.         emit(lobyte(Result));
  1450.         return;
  1451.         }
  1452.     if(Result==0){
  1453.         emit(op+0x20);
  1454.         Cycles--;       /* ,x slightly faster */
  1455.         return;
  1456.         }
  1457.     if(Result>0 && Result <=0xFF){
  1458.         emit(op+0x10);
  1459.         emit(lobyte(Result));
  1460.         return;
  1461.         }
  1462.     if( op < 0x80 ){
  1463.         warn("Value Truncated");
  1464.         emit(op+0x10);
  1465.         emit(lobyte(Result));
  1466.         return;
  1467.         }
  1468.     emit(op);
  1469.     eword(Result);
  1470.     Cycles++;       /* 2 byte slightly slower */
  1471.     return;
  1472. }
  1473. SHAR_EOF
  1474. cat << \SHAR_EOF > DO9.C
  1475. /*
  1476.  *      MC6809 specific processing
  1477.  */
  1478.  
  1479. #define PAGE2    0x10
  1480. #define PAGE3    0x11
  1481. #define IPBYTE    0x9F    /* extended indirect postbyte */
  1482. #define SWI     0x3F
  1483.  
  1484. /* register names */
  1485.  
  1486. #define RD    0
  1487. #define RX    1
  1488. #define RY    2
  1489. #define RU    3
  1490. #define RS    4
  1491. #define RPC    5
  1492. #define RA    8
  1493. #define RB    9
  1494. #define RCC    10
  1495. #define RDP    11
  1496. #define RPCR    12
  1497.  
  1498. /* convert tfr/exg reg number into psh/pul format */
  1499. int     regs[] = { 6,16,32,64,64,128,0,0,2,4,1,8,0};
  1500. int     rcycl[]= { 2,2, 2, 2, 2, 2,  0,0,1,1,1,1,0};
  1501.  
  1502. /* addressing modes */
  1503. #define IMMED   0       /* immediate */
  1504. #define IND     1       /* indexed */
  1505. #define INDIR   2       /* indirect */
  1506. #define OTHER   3       /* NOTA */
  1507.  
  1508. /*
  1509.  *      localinit --- machine specific initialization
  1510.  */
  1511. localinit()
  1512. {
  1513. }
  1514.  
  1515. /*
  1516.  *      do_op --- process mnemonic
  1517.  *
  1518.  *    Called with the base opcode and it's class. Optr points to
  1519.  *    the beginning of the operand field.
  1520.  */
  1521. do_op(opcode,class)
  1522. int opcode;    /* base opcode */
  1523. int class;    /* mnemonic class */
  1524. {
  1525.     int     dist;   /* relative branch distance */
  1526.     int     src,dst;/* source and destination registers */
  1527.     int     pbyte;  /* postbyte value */
  1528.     int     amode;  /* indicated addressing mode */
  1529.     int    j;
  1530.  
  1531.     amode = set_mode();     /* pickup indicated addressing mode */
  1532.  
  1533.     switch(class){
  1534.         case INH:                       /* inherent addressing */
  1535.             emit(opcode);
  1536.             return;
  1537.         case GEN:                       /* general addressing */
  1538.             do_gen(opcode,amode);
  1539.             return;
  1540.         case IMM:                       /* immediate addressing */
  1541.             if( amode != IMMED ){
  1542.                 error("Immediate Operand Required");
  1543.                 return;
  1544.                 }
  1545.             Optr++;
  1546.             eval();
  1547.             emit(opcode);
  1548.             emit(lobyte(Result));
  1549.             return;
  1550.         case REL:                       /* short relative branches */
  1551.             eval();
  1552.             dist = Result - (Pc+2);
  1553.             emit(opcode);
  1554.             if( (dist >127 || dist <-128) && Pass==2){
  1555.                 error("Branch out of Range");
  1556.                 emit(lobyte(-2));
  1557.                 return;
  1558.                 }
  1559.             emit(lobyte(dist));
  1560.             return;
  1561.         case P2REL:                     /* long relative branches */
  1562.             eval();
  1563.             dist = Result - (Pc+4);
  1564.             emit(PAGE2);
  1565.             emit(opcode);
  1566.             eword(dist);
  1567.             return;
  1568.         case P1REL:                     /* lbra and lbsr */
  1569.             if( amode == IMMED)
  1570.                 Optr++; /* kludge for C compiler */
  1571.             eval();
  1572.             dist = Result - (Pc+3);
  1573.             emit(opcode);
  1574.             eword(dist);
  1575.             return;
  1576.         case NOIMM:
  1577.             if( amode == IMMED ){
  1578.                 error("Immediate Addressing Illegal");
  1579.                 return;
  1580.                 }
  1581.             do_gen(opcode,amode);
  1582.             return;
  1583.         case P2GEN:
  1584.             emit(PAGE2);
  1585.             if( amode == IMMED ){
  1586.                 emit(opcode);
  1587.                 Optr++;
  1588.                 eval();
  1589.                 eword(Result);
  1590.                 return;
  1591.                 }
  1592.             do_gen(opcode,amode);
  1593.             return;
  1594.         case P3GEN:
  1595.             emit(PAGE3);
  1596.             if( amode == IMMED ){
  1597.                 emit(opcode);
  1598.                 Optr++;
  1599.                 eval();
  1600.                 eword(Result);
  1601.                 return;
  1602.                 }
  1603.             do_gen(opcode,amode);
  1604.             return;
  1605.         case RTOR:                      /* tfr and exg */
  1606.             emit(opcode);
  1607.             src = regnum();
  1608.             while(alpha(*Optr))Optr++;
  1609.             if(src==ERR){
  1610.                 error("Register Name Required");
  1611.                 emit(0);
  1612.                 return;
  1613.                 }
  1614.             if(*Optr++ != ','){
  1615.                 error("Missing ,");
  1616.                 emit(0);
  1617.                 return;
  1618.                 }
  1619.             dst = regnum();
  1620.             while(alpha(*Optr))Optr++;
  1621.             if(dst==ERR){
  1622.                 error("Register Name Required");
  1623.                 emit(0);
  1624.                 return;
  1625.                 }
  1626.             if( src==RPCR || dst==RPCR){
  1627.                 error("PCR illegal here");
  1628.                 emit(0);
  1629.                 return;
  1630.                 }
  1631.             if( (src <=5 && dst >=8) ||
  1632.                 (src >=8 && dst <=5)){
  1633.                 error("Register Size Mismatch");
  1634.                 emit(0);
  1635.                 return;
  1636.                 }
  1637.             emit( (src<<4)+dst );
  1638.             return;
  1639.         case INDEXED:                   /* indexed addressing only */
  1640.             if( *Optr == '#'){
  1641.                 Optr++;         /* kludge city */
  1642.                 amode = IND;
  1643.                 }
  1644.             if( amode != IND ){
  1645.                 error("Indexed Addressing Required");
  1646.                 return;
  1647.                 }
  1648.             do_indexed(opcode);
  1649.             return;
  1650.         case RLIST:                     /* pushes and pulls */
  1651.             if(*Operand == EOS){
  1652.                 error("Register List Required");
  1653.                 return;
  1654.                 }
  1655.             emit(opcode);
  1656.             pbyte = 0;
  1657.             do{
  1658.                 j = regnum();
  1659.                 if( j == ERR || j==RPCR)
  1660.                     error("Illegal Register Name");
  1661.                 else if(j==RS && (opcode==52))
  1662.                     error("Can't Push S on S");
  1663.                 else if(j==RU && (opcode==54))
  1664.                     error("Can't Push U on U");
  1665.                 else if(j==RS && (opcode==53))
  1666.                     error("Can't Pull S from S");
  1667.                 else if(j==RU && (opcode==55))
  1668.                     error("Can't Pull U from U");
  1669.                 else{
  1670.                     pbyte |= regs[j];
  1671.                     Cycles += rcycl[j];
  1672.                     }
  1673.                 while(*Optr != EOS && alpha(*Optr))Optr++;
  1674.             }while( *Optr++ == ',' );
  1675.             emit(lobyte(pbyte));
  1676.             return;
  1677.         case P2NOIMM:
  1678.             if( amode == IMMED )
  1679.                 error("Immediate Addressing Illegal");
  1680.             else{
  1681.                 emit(PAGE2);
  1682.                 do_gen(opcode,amode);
  1683.                 }
  1684.             return;
  1685.         case P2INH:                     /* Page 2 inherent */
  1686.             emit(PAGE2);
  1687.             emit(opcode);
  1688.             return;
  1689.         case P3INH:                     /* Page 3 inherent */
  1690.             emit(PAGE3);
  1691.             emit(opcode);
  1692.             return;
  1693.         case LONGIMM:
  1694.             if( amode == IMMED ){
  1695.                 emit(opcode);
  1696.                 Optr++;
  1697.                 eval();
  1698.                 eword(Result);
  1699.                 }
  1700.             else
  1701.                 do_gen(opcode,amode);
  1702.             return;
  1703.         case GRP2:
  1704.             if( amode == IND ){
  1705.                 do_indexed(opcode+0x60);
  1706.                 return;
  1707.                 }
  1708.             else if( amode == INDIR){
  1709.                 Optr++;
  1710.                 emit(opcode + 0x60);
  1711.                 emit(IPBYTE);
  1712.                 eval();
  1713.                 eword(Result);
  1714.                 Cycles += 7;
  1715.                 if(*Optr == ']'){
  1716.                     Optr++;
  1717.                     return;
  1718.                     }
  1719.                 error("Missing ']'");
  1720.                 return;
  1721.                 }
  1722.             eval();
  1723.             if(Force_word){
  1724.                 emit(opcode+0x70);
  1725.                 eword(Result);
  1726.                 Cycles += 3;
  1727.                 return;
  1728.                 }
  1729.             if(Force_byte){
  1730.                 emit(opcode);
  1731.                 emit(lobyte(Result));
  1732.                 Cycles += 2;
  1733.                 return;
  1734.                 }
  1735.             if(Result>=0 && Result <=0xFF){
  1736.                 emit(opcode);
  1737.                 emit(lobyte(Result));
  1738.                 Cycles += 2;
  1739.                 return;
  1740.                 }
  1741.             else {
  1742.                 emit(opcode+0x70);
  1743.                 eword(Result);
  1744.                 Cycles += 3;
  1745.                 return;
  1746.                 }
  1747.         case SYS:                       /* system call */
  1748.             emit(SWI);
  1749.             eval();
  1750.             emit(lobyte(Result));
  1751.             return;
  1752.         default:
  1753.             fatal("Error in Mnemonic table");
  1754.         }
  1755. }
  1756.  
  1757.  
  1758. /*
  1759.  *      do_gen --- process general addressing mode stuff
  1760.  */
  1761. do_gen(op,mode)
  1762. int     op;
  1763. int     mode;
  1764. {
  1765.     if( mode == IMMED){
  1766.         Optr++;
  1767.         emit(op);
  1768.         eval();
  1769.         emit(lobyte(Result));
  1770.         return;
  1771.         }
  1772.     else if( mode == IND ){
  1773.         do_indexed(op+0x20);
  1774.         return;
  1775.         }
  1776.     else if( mode == INDIR){
  1777.         Optr++;
  1778.         emit(op+0x20);
  1779.         emit(IPBYTE);
  1780.         eval();
  1781.         eword(Result);
  1782.         Cycles += 7;
  1783.         if(*Optr == ']'){
  1784.             Optr++;
  1785.             return;
  1786.             }
  1787.         error("Missing ']'");
  1788.         return;
  1789.         }
  1790.     else if( mode == OTHER){
  1791.         eval();
  1792.         if(Force_word){
  1793.             emit(op+0x30);
  1794.             eword(Result);
  1795.             Cycles += 3;
  1796.             return;
  1797.             }
  1798.         if(Force_byte){
  1799.             emit(op+0x10);
  1800.             emit(lobyte(Result));
  1801.             Cycles += 2;
  1802.             return;
  1803.             }
  1804.         if(Result>=0 && Result <=0xFF){
  1805.             emit(op+0x10);
  1806.             emit(lobyte(Result));
  1807.             Cycles += 2;
  1808.             return;
  1809.             }
  1810.         else {
  1811.             emit(op+0x30);
  1812.             eword(Result);
  1813.             Cycles += 3;
  1814.             return;
  1815.             }
  1816.         }
  1817.     else {
  1818.         error("Unknown Addressing Mode");
  1819.         return;
  1820.         }
  1821. }
  1822.  
  1823. /*
  1824.  *      do_indexed --- handle all wierd stuff for indexed addressing
  1825.  */
  1826. do_indexed(op)
  1827. int op;
  1828. {
  1829.     int     pbyte;
  1830.     int     j,k;
  1831.     int     predec,pstinc;
  1832.  
  1833.     Cycles += 2;    /* indexed is always 2+ base cycle count */
  1834.     predec=0;
  1835.     pstinc=0;
  1836.     pbyte=128;
  1837.     emit(op);
  1838.     if(*Optr=='['){
  1839.         pbyte |= 0x10;    /* set indirect bit */
  1840.         Optr++;
  1841.         if( !any((char)']',Optr))
  1842.             error("Missing ']'");
  1843.         Cycles += 3;    /* indirection takes this much longer */
  1844.         }
  1845.     j=regnum();
  1846.     if(j==RA){
  1847.         Cycles++;
  1848.         abd_index(pbyte+6);
  1849.         return;
  1850.         }
  1851.     if(j==RB){
  1852.         Cycles++;
  1853.         abd_index(pbyte+5);
  1854.         return;
  1855.         }
  1856.     if(j==RD){
  1857.         Cycles += 4;
  1858.         abd_index(pbyte+11);
  1859.         return;
  1860.         }
  1861.     eval();
  1862.     Optr++;
  1863.     while(*Optr=='-'){
  1864.         predec++;
  1865.         Optr++;
  1866.         }
  1867.     j=regnum();
  1868.     while( alpha(*Optr) )Optr++;
  1869.     while(*Optr=='+'){
  1870.         pstinc++;
  1871.         Optr++;
  1872.         }
  1873.     if(j==RPC || j==RPCR){
  1874.         if( pstinc || predec ){
  1875.             error("Auto Inc/Dec Illegal on PC");
  1876.             return;
  1877.             }
  1878.         if(j==RPC){
  1879.             if(Force_word){
  1880.                 emit(pbyte+13);
  1881.                 eword(Result);
  1882.                 Cycles += 5;
  1883.                 return;
  1884.                 }
  1885.             if(Force_byte){
  1886.                 emit(pbyte+12);
  1887.                 emit(lobyte(Result));
  1888.                 Cycles++;
  1889.                 return;
  1890.                 }
  1891.             if(Result>=-128 && Result <=127){
  1892.                 emit(pbyte+12);
  1893.                 emit(lobyte(Result));
  1894.                 Cycles++;
  1895.                 return;
  1896.                 }
  1897.             else {
  1898.                 emit(pbyte+13);
  1899.                 eword(Result);
  1900.                 Cycles += 5;
  1901.                 return;
  1902.                 }
  1903.             }
  1904.         /* PCR addressing */
  1905.         if(Force_word){
  1906.             emit(pbyte+13);
  1907.             eword(Result-(Pc+2));
  1908.             Cycles += 5;
  1909.             return;
  1910.             }
  1911.         if(Force_byte){
  1912.             emit(pbyte+12);
  1913.             emit(lobyte(Result-(Pc+1)));
  1914.             Cycles++;
  1915.             return;
  1916.             }
  1917.         k=Result-(Pc+2);
  1918.         if( k >= -128 && k <= 127){
  1919.             emit(pbyte+12);
  1920.             emit(lobyte(Result-(Pc+1)));
  1921.             Cycles++;
  1922.             return;
  1923.             }
  1924.         else{
  1925.             emit(pbyte+13);
  1926.             eword(Result-(Pc+2));
  1927.             Cycles += 5;
  1928.             return;
  1929.             }
  1930.         }
  1931.     if(predec || pstinc){
  1932.         if(Result != 0){
  1933.             error("Offset must be Zero");
  1934.             return;
  1935.             }
  1936.         if(predec>2 || pstinc>2){
  1937.             error("Auto Inc/Dec by 1 or 2 only");
  1938.             return;
  1939.             }
  1940.         if((predec==1 && (pbyte&0x10) != 0) ||
  1941.            (pstinc==1 && (pbyte&0x10) != 0)){
  1942.             error("No Auto Inc/Dec by 1 for Indirect");
  1943.             return;
  1944.             }
  1945.         if(predec && pstinc){
  1946.             error("Can't do both!");
  1947.             return;
  1948.             }
  1949.         if(predec)
  1950.             pbyte += predec+1;
  1951.         if(pstinc)
  1952.             pbyte += pstinc-1;
  1953.         pbyte += rtype(j);
  1954.         emit(pbyte);
  1955.         Cycles += 1 + predec + pstinc;
  1956.         return;
  1957.         }
  1958.     pbyte += rtype(j);
  1959.     if(Force_word){
  1960.         emit(pbyte+0x09);
  1961.         eword(Result);
  1962.         Cycles += 4;
  1963.         return;
  1964.         }
  1965.     if(Force_byte){
  1966.         emit(pbyte+0x08);
  1967.         emit(lobyte(Result));
  1968.         Cycles++;
  1969.         return;
  1970.         }
  1971.     if(Result==0){
  1972.         emit(pbyte+0x04);
  1973.         return;
  1974.         }
  1975.     if((Result >= -16) && (Result <= 15) && ((pbyte&16)==0)){
  1976.         pbyte &= 127;
  1977.         pbyte += Result&31;
  1978.         emit(pbyte);
  1979.         Cycles++;
  1980.         return;
  1981.         }
  1982.     if(Result >= -128 && Result <= 127){
  1983.         emit(pbyte+0x08);
  1984.         emit(lobyte(Result));
  1985.         Cycles++;
  1986.         return;
  1987.         }
  1988.     emit(pbyte+0x09);
  1989.     eword(Result);
  1990.     Cycles += 4;
  1991.     return;
  1992. }
  1993.  
  1994.  
  1995. /*
  1996.  *      abd_index --- a,b or d indexed
  1997.  */
  1998.  
  1999. abd_index(pbyte)
  2000. int pbyte;
  2001. {
  2002.     int     k;
  2003.  
  2004.     Optr += 2;
  2005.     k=regnum();
  2006.     pbyte += rtype(k);
  2007.     emit(pbyte);
  2008.     return;
  2009. }
  2010.  
  2011. /*
  2012.  *      rtype --- return register type in post-byte format
  2013.  */
  2014. rtype(r)
  2015. int r;
  2016. {
  2017.     switch(r){
  2018.     case RX:        return(0x00);
  2019.     case RY:        return(0x20);
  2020.     case RU:        return(0x40);
  2021.     case RS:        return(0x60);
  2022.         }
  2023.     error("Illegal Register for Indexed");
  2024.     return(0);
  2025. }
  2026.  
  2027. /*
  2028.  *      set_mode --- determine addressing mode from operand field
  2029.  */
  2030. set_mode()
  2031. {
  2032.     register char *p;
  2033.  
  2034.     if( *Operand == '#' )
  2035.         return(IMMED);          /* immediate addressing */
  2036.     p = Operand;
  2037.     while( *p != EOS && *p != BLANK && *p != TAB){/* any , before break */
  2038.         if( *p == ',')
  2039.             return(IND);    /* indexed addressing */
  2040.         p++;
  2041.         }
  2042.     if( *Operand == '[')
  2043.         return(INDIR);          /* indirect addressing */
  2044.     return(OTHER);                  /* NOTA */
  2045. }
  2046.  
  2047. /*
  2048.  *      regnum --- return register number of *Optr
  2049.  */
  2050. regnum()
  2051. {
  2052.     if( head(Optr,"D" ))return(RD);
  2053.     if( head(Optr,"d" ))return(RD);
  2054.     if( head(Optr,"X" ))return(RX);
  2055.     if( head(Optr,"x" ))return(RX);
  2056.     if( head(Optr,"Y" ))return(RY);
  2057.     if( head(Optr,"y" ))return(RY);
  2058.     if( head(Optr,"U" ))return(RU);
  2059.     if( head(Optr,"u" ))return(RU);
  2060.     if( head(Optr,"S" ))return(RS);
  2061.     if( head(Optr,"s" ))return(RS);
  2062.     if( head(Optr,"PC" ))return(RPC);
  2063.     if( head(Optr,"pc" ))return(RPC);
  2064.     if( head(Optr,"PCR" ))return(RPCR);
  2065.     if( head(Optr,"pcr" ))return(RPCR);
  2066.     if( head(Optr,"A" ))return(RA);
  2067.     if( head(Optr,"a" ))return(RA);
  2068.     if( head(Optr,"B" ))return(RB);
  2069.     if( head(Optr,"b" ))return(RB);
  2070.     if( head(Optr,"CC" ))return(RCC);
  2071.     if( head(Optr,"cc" ))return(RCC);
  2072.     if( head(Optr,"DP" ))return(RDP);
  2073.     if( head(Optr,"dp" ))return(RDP);
  2074.     return(ERR);
  2075. }
  2076.  
  2077. SHAR_EOF
  2078. cat << \SHAR_EOF > FFWD.C
  2079. /*
  2080.  *      file I/O version of forward ref handler
  2081.  */
  2082.  
  2083. #define    FILEMODE    0644    /* file creat mode */
  2084. #define    UPDATE        2    /* file open mode */
  2085. #define    ABS        0    /* absolute seek */
  2086.  
  2087. int    Forward =0;        /* temp file's file descriptor    */
  2088. char    Fwd_name[] = { "Fwd_refs" } ;
  2089.  
  2090. /*
  2091.  *      fwdinit --- initialize forward ref file
  2092.  */
  2093. fwdinit()
  2094. {
  2095.     Forward = creat(Fwd_name,FILEMODE);
  2096.     if(Forward <0)
  2097.         fatal("Can't create temp file");
  2098.     close(Forward); /* close and reopen for reads and writes */
  2099.     Forward = open(Fwd_name,UPDATE);
  2100.     if(Forward <0)
  2101.         fatal("Forward ref file has gone.");
  2102. #ifndef DEBUG
  2103.     unlink(Fwd_name);
  2104. #endif
  2105. }
  2106.  
  2107. /*
  2108.  *      fwdreinit --- reinitialize forward ref file
  2109.  */
  2110. fwdreinit()
  2111. {
  2112.     F_ref   = 0;
  2113.     Ffn     = 0;
  2114.     lseek(Forward,0L,ABS);   /* rewind forward refs */
  2115.     read(Forward,&Ffn,sizeof(Ffn));
  2116.     read(Forward,&F_ref,sizeof(F_ref)); /* read first forward ref into mem */
  2117. #ifdef DEBUG
  2118.     printf("First fwd ref: %d,%d\n",Ffn,F_ref);
  2119. #endif
  2120. }
  2121.  
  2122. /*
  2123.  *      fwdmark --- mark current file/line as containing a forward ref
  2124.  */
  2125. fwdmark()
  2126. {
  2127.     write(Forward,&Cfn,sizeof(Cfn));
  2128.     write(Forward,&Line_num,sizeof(Line_num));
  2129. }
  2130.  
  2131. /*
  2132.  *      fwdnext --- get next forward ref
  2133.  */
  2134. fwdnext()
  2135. {
  2136.     int stat;
  2137.  
  2138.     stat = read(Forward,&Ffn,sizeof(Ffn));
  2139. #ifdef DEBUG
  2140.     printf("Ffn stat=%d ",stat);
  2141. #endif
  2142.     stat = read(Forward,&F_ref,sizeof(F_ref));
  2143. #ifdef DEBUG
  2144.     printf("F_ref stat=%d  ",stat);
  2145. #endif
  2146.     if( stat < 2 ){
  2147.         F_ref=0;Ffn=0;
  2148.         }
  2149. #ifdef DEBUG
  2150.     printf("Next Fwd ref: %d,%d\n",Ffn,F_ref);
  2151. #endif
  2152. }
  2153. SHAR_EOF
  2154. cat << \SHAR_EOF > OUTPUT.C
  2155. /*
  2156.  *  stable --- prints the symbol table in alphabetical order
  2157.  */
  2158. stable(ptr)
  2159.  
  2160. struct nlist *ptr;
  2161. {
  2162.   if (ptr != NULL)
  2163.     {
  2164.       stable (ptr->Lnext);
  2165.         printf ("%-10s %04x\n",ptr->name,ptr->def);
  2166.       stable (ptr->Rnext);
  2167.     }
  2168. }
  2169. /*
  2170.  *  cross  --  prints the cross reference table 
  2171.  */
  2172. cross(point)
  2173.  
  2174. struct nlist *point;
  2175. {
  2176. struct link *tp;
  2177. int i = 1;
  2178.   if (point != NULL)
  2179.     {
  2180.       cross (point->Lnext);
  2181.         printf ("%-10s %04x *",point->name,point->def);
  2182.          tp = point->L_list;
  2183.           while (tp != NULL)
  2184.            {
  2185.              if (i++>10)
  2186.               {
  2187.                i=1;
  2188.                printf("\n                      ");
  2189.               }
  2190.               printf ("%04d ",tp->L_num);
  2191.                tp = tp->next;
  2192.            }
  2193.          printf ("\n");
  2194.       cross (point->Rnext);
  2195.     }
  2196. }
  2197. SHAR_EOF
  2198. cat << \SHAR_EOF > PSEUDO.C
  2199. /*
  2200.  *      pseudo --- pseudo op processing
  2201.  */
  2202.  
  2203. #define RMB     0       /* Reserve Memory Bytes         */
  2204. #define FCB     1       /* Form Constant Bytes          */
  2205. #define FDB     2       /* Form Double Bytes (words)    */
  2206. #define FCC     3       /* Form Constant Characters     */
  2207. #define ORG     4       /* Origin                       */
  2208. #define EQU     5       /* Equate                       */
  2209. #define ZMB     6       /* Zero memory bytes            */
  2210. #define FILL    7       /* block fill constant bytes    */
  2211. #define OPT     8       /* assembler option             */
  2212. #define NULL_OP 9       /* null pseudo op               */
  2213. #define PAGE    10      /* new page                     */
  2214.  
  2215. struct oper pseudo[] = {
  2216. "bsz",  PSEUDO, ZMB,    0,
  2217. "end",  PSEUDO, NULL_OP,0,
  2218. "equ",  PSEUDO, EQU,    0,
  2219. "fcb",  PSEUDO, FCB,    0,
  2220. "fcc",  PSEUDO, FCC,    0,
  2221. "fdb",  PSEUDO, FDB,    0,
  2222. "fill", PSEUDO, FILL,   0,
  2223. "nam",  PSEUDO, NULL_OP,0,
  2224. "name", PSEUDO, NULL_OP,0,
  2225. "opt",  PSEUDO, OPT,    0,
  2226. "org",  PSEUDO, ORG,    0,
  2227. "pag",  PSEUDO, PAGE,   0,
  2228. "page", PSEUDO, PAGE,   0,
  2229. "rmb",  PSEUDO, RMB,    0,
  2230. "spc",  PSEUDO, NULL_OP,0,
  2231. "ttl",  PSEUDO, NULL_OP,0,
  2232. "zmb",  PSEUDO, ZMB,    0
  2233. };
  2234.  
  2235. /*
  2236.  *      do_pseudo --- do pseudo op processing
  2237.  */
  2238. do_pseudo(op)
  2239. int op; /* which op */
  2240. {
  2241.         char    fccdelim;
  2242.         int     j;
  2243.         int     fill;
  2244.         char    *skip_white();
  2245.  
  2246.         if( op != EQU && *Label )
  2247.                 install(Label,Pc);
  2248.  
  2249.         P_force++;
  2250.         switch(op){
  2251.                 case RMB:                       /* reserve memory bytes */
  2252.                         if( eval() ){
  2253.                                 Pc +=  Result;
  2254.                                 f_record();     /* flush out bytes */
  2255.                                 }
  2256.                         else
  2257.                                 error("Undefined Operand during Pass One");
  2258.                         break;
  2259.                 case ZMB:                       /* zero memory bytes */
  2260.                         if( eval() )
  2261.                                 while( Result-- )
  2262.                                         emit(0);
  2263.                         else
  2264.                                 error("Undefined Operand during Pass One");
  2265.                         break;
  2266.                 case FILL:                      /* fill memory with constant */
  2267.                         eval();
  2268.                         fill = Result;
  2269.                         if( *Optr++ != ',' )
  2270.                                 error("Bad fill");
  2271.                         else{
  2272.                                 Optr = skip_white(Optr);
  2273.                                 eval();
  2274.                                 while( Result-- )
  2275.                                         emit(fill);
  2276.                                 }
  2277.                         break;
  2278.                 case FCB:                       /* form constant byte(s) */
  2279.                         do{
  2280.                                 Optr = skip_white(Optr);
  2281.                                 eval();
  2282.                                 if( Result > 0xFF ){
  2283.                                         if(!Force_byte)
  2284.                                                 warn("Value truncated");
  2285.                                         Result = lobyte(Result);
  2286.                                         }
  2287.                                 emit(Result);
  2288.                         }while( *Optr++ == ',' );
  2289.                         break;
  2290.                 case FDB:                       /* form double byte(s) */
  2291.                         do{
  2292.                                 Optr = skip_white(Optr);
  2293.                                 eval();
  2294.                                 eword(Result);
  2295.                         }while( *Optr++ == ',' );
  2296.                         break;
  2297.                 case FCC:                       /* form constant characters */
  2298.                         if(*Operand==EOS)
  2299.                                 break;
  2300.                         fccdelim = *Optr++;
  2301.                         while( *Optr != EOS && *Optr != fccdelim)
  2302.                                 emit(*Optr++);
  2303.                         if(*Optr == fccdelim)
  2304.                                 Optr++;
  2305.                         else
  2306.                                 error("Missing Delimiter");
  2307.                         break;
  2308.                 case ORG:                       /* origin */
  2309.                         if( eval() ){
  2310.                                 Old_pc = Pc = Result;
  2311.                                 f_record();     /* flush out any bytes */
  2312.                                 }
  2313.                         else
  2314.                                 error("Undefined Operand during Pass One");
  2315.                         break;
  2316.                 case EQU:                       /* equate */
  2317.                         if(*Label==EOS){
  2318.                                 error("EQU requires label");
  2319.                                 break;
  2320.                                 }
  2321.                         if( eval() ){
  2322.                                 install(Label,Result);
  2323.                                 Old_pc = Result;        /* override normal */
  2324.                                 }
  2325.                         else
  2326.                                 error("Undefined Operand during Pass One");
  2327.                         break;
  2328.                 case OPT:                       /* assembler option */
  2329.                         P_force=0;
  2330.                         if( head(Operand,"l") )
  2331.                                 Lflag=1;
  2332.                         else if( head(Operand,"nol"))
  2333.                                 Lflag=0;
  2334.                         else if( head(Operand,"c")){
  2335.                                 Cflag=1;
  2336.                                 Ctotal=0;
  2337.                                 }
  2338.                         else if( head(Operand,"noc"))
  2339.                                 Cflag=0;
  2340.                         else if( head(Operand,"contc")){
  2341.                                 Cflag=1;
  2342.                                 }
  2343.                         else if ( head(Operand,"s"))
  2344.                                 Sflag = 1;
  2345.                         else if ( head(Operand,"cre"))
  2346.                                 CREflag = 1;
  2347.                         else
  2348.                                 error("Unrecognized OPT");
  2349.                         break;
  2350.                 case PAGE:                      /* go to a new page */
  2351.                         P_force=0;
  2352.                         N_page = 1;
  2353.                         if (Pass == 2 )
  2354.                          if (Lflag)  
  2355.                           {
  2356.                            printf ("\f");
  2357.                            printf ("%-10s",Argv[Cfn]);
  2358.                            printf ("                                   ");
  2359.                            printf ("page %3d\n",Page_num++);
  2360.                           }
  2361.                         break;
  2362.                 case NULL_OP:                   /* ignored psuedo ops */
  2363.                         P_force=0;
  2364.                         break;
  2365.                 default:
  2366.                         fatal("Pseudo error");
  2367.                 }
  2368. }
  2369. SHAR_EOF
  2370. #    End of shell archive
  2371. exit 0
  2372. -- 
  2373. Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
  2374. Have five nice days.
  2375.